import streamlit as st
import os
import json
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime
from PIL import Image
import time
import glob
import zipfile
import io
import numpy as np

from models.enhanced_evaluator import EnhancedEvaluator
from utils.helpers import get_products_from_data_dir, get_product_stats, create_experiment_log, load_evaluation_results, get_experiment_logs

def show_multi_algo_evaluation():
    """显示多算法系统测评页面"""
    
    st.title("多算法缺陷检测测评")
    
    # 初始化会话状态
    if "vllm_model" not in st.session_state:
        st.session_state.vllm_model = None
    
    if "knowledge_base" not in st.session_state:
        st.session_state.knowledge_base = None
    
    # 检查模型和知识库是否已加载
    if st.session_state.vllm_model is None:
        st.warning("请先在'缺陷检测'或'对话模式'页面配置VLLM模型")
        return
    
    if st.session_state.knowledge_base is None:
        st.warning("请先在'知识库管理'页面加载CLIP模型和知识库")
        return
    
    # 设置评估目录
    data_dir = "./data"
    result_dir = "./evaluation_results/multi_algo"
    os.makedirs(result_dir, exist_ok=True)
    
    # 获取产品列表
    products = get_products_from_data_dir(data_dir)
    
    if not products:
        st.warning("未找到可用的产品数据集。请检查数据目录。")
        return
    
    # 创建标签页
    tab1, tab2, tab3 = st.tabs(["运行评估", "查看结果", "结果可视化"])
    
    # 运行评估页面
    with tab1:
        st.header("运行多算法系统评估")
        
        # 算法介绍
        st.markdown("""
        本页面将评估3种不同的缺陷检测算法：
        
        1. **CLIP投票算法**：仅使用CLIP RAG检索回来的结果进行投票来确定缺陷类型
        2. **纯VLLM算法**：仅使用Qwen 2.5 VL大模型对图像进行识别，不使用RAG
        3. **组合算法**：结合CLIP+RAG+VLLM(Qwen 2.5 VL)的综合方法（现有系统）
        """)
        
        # 模型信息显示
        col1, col2 = st.columns(2)
        with col1:
            st.info(f"当前CLIP模型: {st.session_state.clip_model.model_name}")
        with col2:
            st.info(f"当前VLLM模型: {st.session_state.vllm_model.model_name}")
        
        # 选择要评估的产品
        st.subheader("选择产品")
        
        # 默认选中所有产品
        all_products = st.checkbox("选择所有产品", value=True)
        
        if all_products:
            selected_products = products
            st.success(f"已选择所有 {len(products)} 个产品")
        else:
            selected_products = st.multiselect("选择要评估的产品", products)
        
        if not selected_products:
            st.warning("请至少选择一个产品")
            return
        
        # 配置测评参数
        st.subheader("测评配置")
        
        # 实验名称
        experiment_name = st.text_input("实验名称", value=f"多算法实验_{datetime.now().strftime('%Y%m%d_%H%M%S')}")
        
        # 评估参数
        eval_params = {}
        with st.expander("高级配置"):
            eval_params["auto_save_interval"] = st.slider("自动保存间隔(评估产品数)", 1, 5, 1)
            eval_params["show_detailed_progress"] = st.checkbox("显示详细进度", value=True)
        
        # 启动评估
        if st.button("开始评估", key="start_multi_evaluation", type="primary"):
            # 创建增强评估器
            evaluator = EnhancedEvaluator(data_dir=data_dir, result_dir=result_dir)
            
            # 构建组合算法测试函数
            def combined_detect_function(image_path, product_name, retrieval_results):
                return st.session_state.vllm_model.detect_defect(
                    image_path=image_path,
                    product_name=product_name,
                    knowledge_results=retrieval_results
                )
            
            # 记录参数
            params = {
                "clip_model": st.session_state.clip_model.model_name,
                "vllm_model": st.session_state.vllm_model.model_name,
                "products": selected_products,
                "timestamp": datetime.now().isoformat()
            }
            
            # 创建实验日志
            log_file = create_experiment_log(experiment_name, params, result_dir)
            
            # 创建进度条
            progress_bar = st.progress(0)
            status_text = st.empty()
            
            # 评估总体开始时间
            total_start_time = time.time()
            
            # 对每个产品进行评估
            all_metrics = {}
            
            # 创建用于显示当前测评信息的区域
            current_eval_container = st.container()
            with current_eval_container:
                st.subheader("当前测评进度")
                
                # 当前产品信息
                current_product_info = st.empty()
                
                # 创建列以显示当前图片和结果
                current_image_col, current_results_col = st.columns([1, 2])
                
                with current_image_col:
                    current_image_holder = st.empty()
                
                with current_results_col:
                    current_rag_holder = st.empty()
                    current_algorithms_holder = st.empty()
                
                # 创建实时指标显示区域
                metrics_container = st.container()
                with metrics_container:
                    st.subheader("实时评估指标")
                    metrics_placeholder = st.empty()
            
            # 定义回调函数，用于展示评估过程中的信息
            def display_multi_evaluation_progress(img_path, retrieval_results, all_results):
                # 获取当前产品名称
                product_name = os.path.basename(os.path.dirname(os.path.dirname(img_path)))
                
                # 显示当前产品
                current_product_info.info(f"正在评估产品: **{product_name}**")
                
                # 显示当前图片
                try:
                    image = Image.open(img_path)
                    current_image_holder.image(image, caption=f"当前测试图片: {os.path.basename(img_path)}", use_column_width=True)
                except Exception as e:
                    current_image_holder.error(f"无法加载图片: {str(e)}")
                
                # 显示RAG结果
                rag_html = "<h4>知识库检索结果:</h4><ul>"
                for i, res in enumerate(retrieval_results[:3]):  # 只显示前3个结果
                    similarity = res.get("similarity", 0.0)
                    label = res.get("label", "未知")
                    path = res.get("path", "")
                    filename = os.path.basename(path)
                    rag_html += f"<li>{label} ({similarity:.4f}): {filename}</li>"
                rag_html += "</ul>"
                current_rag_holder.markdown(rag_html, unsafe_allow_html=True)
                
                # 显示三种算法的结果
                algorithms_html = "<h4>三种算法的检测结果:</h4>"
                
                # 获取真实标签
                true_label = os.path.basename(os.path.dirname(img_path))
                true_has_defect = true_label.lower() != "good"
                
                # 添加真实标签信息
                algorithms_html += f"<p><b>真实标签:</b> {true_label} ({'有缺陷' if true_has_defect else '无缺陷'})</p>"
                
                # 算法名称映射
                alg_names = {
                    "clip_voting": "CLIP投票算法",
                    "vllm_only": "纯VLLM算法",
                    "combined": "组合算法"
                }
                
                # 添加每种算法的预测结果
                for alg in ["clip_voting", "vllm_only", "combined"]:
                    # 获取最后一个结果（当前图片）
                    if len(all_results.get(alg, [])) > 0:
                        result = all_results[alg][-1]
                        
                        # 获取预测结果
                        pred_result = result["prediction"]
                        if isinstance(pred_result, str):
                            try:
                                # 尝试提取JSON部分
                                start = pred_result.find("{")
                                end = pred_result.rfind("}") + 1
                                if start >= 0 and end > start:
                                    json_str = pred_result[start:end]
                                    pred_result = json.loads(json_str)
                            except:
                                pred_result = {"has_defect": None, "defect_type": None, "confidence": None}
                        
                        # 提取关键信息
                        has_defect = pred_result.get("has_defect", None)
                        defect_type = pred_result.get("defect_type", "unknown")
                        confidence = pred_result.get("confidence", 0.0)
                        analysis = pred_result.get("analysis", "")
                        
                        # 判断是否正确
                        is_correct = (has_defect == true_has_defect) and (has_defect is False or defect_type.lower() == true_label.lower())
                        
                        algorithms_html += f"<div style='margin-top: 15px; padding: 10px; border-left: 4px solid {'green' if is_correct else 'red'}; background-color: {'#f0fff0' if is_correct else '#fff0f0'};'>"
                        algorithms_html += f"<h5>{alg_names[alg]}:</h5>"
                        algorithms_html += f"<p>预测结果: <b>{defect_type}</b> ({'有缺陷' if has_defect else '无缺陷'})</p>"
                        algorithms_html += f"<p>置信度: <b>{confidence:.4f}</b></p>"
                        algorithms_html += f"<p>判断: <b style='color:{'green' if is_correct else 'red'};'>{'✓ 正确' if is_correct else '✗ 错误'}</b></p>"
                        algorithms_html += f"<p>分析: {analysis}</p>"
                        algorithms_html += "</div>"
                
                current_algorithms_holder.markdown(algorithms_html, unsafe_allow_html=True)
                
                # 短暂暂停，让用户有时间查看
                time.sleep(0.2)
            
            # 产品级别的评估
            for i, product in enumerate(selected_products):
                # 更新状态
                status_text.text(f"正在评估产品 {i+1}/{len(selected_products)}: {product}...")
                progress_bar.progress((i) / len(selected_products))
                
                # 检查知识库是否已存在
                product_kb_exists = False
                try:
                    # 尝试加载知识库
                    if product in st.session_state.knowledge_base.get_product_list():
                        st.info(f"知识库 {product} 已存在，将直接使用")
                        product_kb_exists = st.session_state.knowledge_base.load_or_create(product)
                except Exception as e:
                    st.warning(f"加载知识库 {product} 失败: {str(e)}")
                
                # 如果知识库不存在，则创建
                if not product_kb_exists:
                    with st.spinner(f"为 {product} 构建知识库..."):
                        train_dir = os.path.join(data_dir, product, "train")
                        st.session_state.knowledge_base.build_from_folder(
                            product_name=product,
                            data_dir=train_dir
                        )
                
                # 运行多算法评估
                with st.spinner(f"评估 {product} 的三种算法性能..."):
                    metrics = evaluator.evaluate_product_with_all_algorithms(
                        product_name=product,
                        vllm_model=st.session_state.vllm_model,
                        knowledge_base=st.session_state.knowledge_base,
                        combined_detect_fn=combined_detect_function,
                        callback=display_multi_evaluation_progress if eval_params.get("show_detailed_progress", True) else None
                    )
                
                # 显示当前产品的三种算法对比指标
                metrics_df = pd.DataFrame({
                    "指标": ["准确率", "精确率", "召回率", "F1分数", "特异度", "MCC"],
                    "CLIP投票算法": [
                        metrics.get("clip_voting", {}).get("accuracy", float('nan')),
                        metrics.get("clip_voting", {}).get("precision", float('nan')),
                        metrics.get("clip_voting", {}).get("recall", float('nan')),
                        metrics.get("clip_voting", {}).get("f1", float('nan')),
                        metrics.get("clip_voting", {}).get("specificity", float('nan')),
                        metrics.get("clip_voting", {}).get("mcc", float('nan'))
                    ],
                    "纯VLLM算法": [
                        metrics.get("vllm_only", {}).get("accuracy", float('nan')),
                        metrics.get("vllm_only", {}).get("precision", float('nan')),
                        metrics.get("vllm_only", {}).get("recall", float('nan')),
                        metrics.get("vllm_only", {}).get("f1", float('nan')),
                        metrics.get("vllm_only", {}).get("specificity", float('nan')),
                        metrics.get("vllm_only", {}).get("mcc", float('nan'))
                    ],
                    "组合算法": [
                        metrics.get("combined", {}).get("accuracy", float('nan')),
                        metrics.get("combined", {}).get("precision", float('nan')),
                        metrics.get("combined", {}).get("recall", float('nan')),
                        metrics.get("combined", {}).get("f1", float('nan')),
                        metrics.get("combined", {}).get("specificity", float('nan')),
                        metrics.get("combined", {}).get("mcc", float('nan'))
                    ]
                })
                
                metrics_placeholder.dataframe(metrics_df, use_container_width=True)
                
                # 保存指标
                all_metrics[product] = metrics
                
                # 如果达到自动保存间隔，则保存中间结果
                auto_save_interval = eval_params.get("auto_save_interval", 1)
                if (i+1) % auto_save_interval == 0 or i == len(selected_products) - 1:
                    # 保存当前结果
                    summary_path = os.path.join(result_dir, "summary_interim.json")
                    with open(summary_path, 'w', encoding='utf-8') as f:
                        json.dump(all_metrics, f, ensure_ascii=False, indent=2)
            
            # 计算总体评估时间
            total_end_time = time.time()
            total_time = total_end_time - total_start_time
            
            # 最终评估完成，汇总所有产品的指标
            all_metrics = evaluator.evaluate_all_products(
                selected_products,
                st.session_state.vllm_model,
                st.session_state.knowledge_base,
                combined_detect_function,
                None
            )
            
            # 完成评估
            progress_bar.progress(1.0)
            status_text.text("评估完成！")
            
            # 显示总体结果
            avg_metrics = all_metrics.get("average", {})
            
            st.success(f"评估完成！总共评估了 {len(selected_products)} 个产品，用时 {total_time:.2f} 秒")
            
            st.subheader("总体评估结果")
            
            # 创建三种算法的平均指标表格
            metrics_df = pd.DataFrame({
                "指标": ["准确率", "精确率", "召回率", "F1分数", "AUC", "特异度", "MCC"],
                "CLIP投票算法": [
                    avg_metrics.get("clip_voting", {}).get("accuracy", float('nan')),
                    avg_metrics.get("clip_voting", {}).get("precision", float('nan')),
                    avg_metrics.get("clip_voting", {}).get("recall", float('nan')),
                    avg_metrics.get("clip_voting", {}).get("f1", float('nan')),
                    avg_metrics.get("clip_voting", {}).get("auc", float('nan')),
                    avg_metrics.get("clip_voting", {}).get("specificity", float('nan')),
                    avg_metrics.get("clip_voting", {}).get("mcc", float('nan'))
                ],
                "纯VLLM算法": [
                    avg_metrics.get("vllm_only", {}).get("accuracy", float('nan')),
                    avg_metrics.get("vllm_only", {}).get("precision", float('nan')),
                    avg_metrics.get("vllm_only", {}).get("recall", float('nan')),
                    avg_metrics.get("vllm_only", {}).get("f1", float('nan')),
                    avg_metrics.get("vllm_only", {}).get("auc", float('nan')),
                    avg_metrics.get("vllm_only", {}).get("specificity", float('nan')),
                    avg_metrics.get("vllm_only", {}).get("mcc", float('nan'))
                ],
                "组合算法": [
                    avg_metrics.get("combined", {}).get("accuracy", float('nan')),
                    avg_metrics.get("combined", {}).get("precision", float('nan')),
                    avg_metrics.get("combined", {}).get("recall", float('nan')),
                    avg_metrics.get("combined", {}).get("f1", float('nan')),
                    avg_metrics.get("combined", {}).get("auc", float('nan')),
                    avg_metrics.get("combined", {}).get("specificity", float('nan')),
                    avg_metrics.get("combined", {}).get("mcc", float('nan'))
                ]
            })
            
            st.dataframe(metrics_df, use_container_width=True)
            
            # 显示各产品各算法的结果对比
            st.subheader("各产品算法评估结果")
            
            # 为每个指标创建对比表格
            metrics_to_show = ["accuracy", "f1", "recall", "precision"]
            metric_names = {"accuracy": "准确率", "f1": "F1分数", "recall": "召回率", "precision": "精确率"}
            
            for metric in metrics_to_show:
                st.markdown(f"#### {metric_names[metric]}对比")
                
                product_metrics = []
                for product in selected_products:
                    product_metrics.append({
                        "产品": product,
                        "CLIP投票算法": all_metrics.get(product, {}).get("clip_voting", {}).get(metric, float('nan')),
                        "纯VLLM算法": all_metrics.get(product, {}).get("vllm_only", {}).get(metric, float('nan')),
                        "组合算法": all_metrics.get(product, {}).get("combined", {}).get(metric, float('nan'))
                    })
                
                product_df = pd.DataFrame(product_metrics)
                st.dataframe(product_df, use_container_width=True)
            
            # 结果保存提示
            st.info(f"详细结果已保存至 {result_dir} 目录")
            
            # 查看图表
            if st.button("查看评估图表"):
                tab3.open()  # 自动打开结果可视化标签页
    
    # 查看结果页面
    with tab2:
        st.header("查看多算法评估结果")
        
        # 检查结果目录
        if not os.path.exists(result_dir):
            st.warning("未找到评估结果目录")
            return
        
        # 加载评估结果
        summary_path = os.path.join(result_dir, "algorithm_comparison_summary.json")
        
        if not os.path.exists(summary_path):
            st.warning("未找到算法对比结果文件")
            return
        
        # 加载结果
        with open(summary_path, 'r', encoding='utf-8') as f:
            all_metrics = json.load(f)
        
        # 显示总体对比结果
        st.subheader("算法总体对比")
        
        # 获取平均指标
        avg_metrics = all_metrics.get("average", {})
        
        # 创建三种算法的平均指标表格
        metrics_df = pd.DataFrame({
            "指标": ["准确率", "精确率", "召回率", "F1分数", "AUC", "特异度", "MCC"],
            "CLIP投票算法": [
                avg_metrics.get("clip_voting", {}).get("accuracy", float('nan')),
                avg_metrics.get("clip_voting", {}).get("precision", float('nan')),
                avg_metrics.get("clip_voting", {}).get("recall", float('nan')),
                avg_metrics.get("clip_voting", {}).get("f1", float('nan')),
                avg_metrics.get("clip_voting", {}).get("auc", float('nan')),
                avg_metrics.get("clip_voting", {}).get("specificity", float('nan')),
                avg_metrics.get("clip_voting", {}).get("mcc", float('nan'))
            ],
            "纯VLLM算法": [
                avg_metrics.get("vllm_only", {}).get("accuracy", float('nan')),
                avg_metrics.get("vllm_only", {}).get("precision", float('nan')),
                avg_metrics.get("vllm_only", {}).get("recall", float('nan')),
                avg_metrics.get("vllm_only", {}).get("f1", float('nan')),
                avg_metrics.get("vllm_only", {}).get("auc", float('nan')),
                avg_metrics.get("vllm_only", {}).get("specificity", float('nan')),
                avg_metrics.get("vllm_only", {}).get("mcc", float('nan'))
            ],
            "组合算法": [
                avg_metrics.get("combined", {}).get("accuracy", float('nan')),
                avg_metrics.get("combined", {}).get("precision", float('nan')),
                avg_metrics.get("combined", {}).get("recall", float('nan')),
                avg_metrics.get("combined", {}).get("f1", float('nan')),
                avg_metrics.get("combined", {}).get("auc", float('nan')),
                avg_metrics.get("combined", {}).get("specificity", float('nan')),
                avg_metrics.get("combined", {}).get("mcc", float('nan'))
            ]
        })
        
        st.dataframe(metrics_df, use_container_width=True)
        
        # 选择要查看的产品
        products = [p for p in all_metrics.keys() if p != "average"]
        product_to_view = st.selectbox("选择产品", ["总体结果"] + products)
        
        if product_to_view == "总体结果":
            # 显示总体结果
            pass  # 已经显示了总体结果表格
        else:
            # 显示特定产品的结果
            st.subheader(f"{product_to_view} 算法对比")
            
            product_metrics = all_metrics.get(product_to_view, {})
            
            # 创建该产品的三种算法指标表格
            metrics_df = pd.DataFrame({
                "指标": ["准确率", "精确率", "召回率", "F1分数", "AUC", "特异度", "MCC"],
                "CLIP投票算法": [
                    product_metrics.get("clip_voting", {}).get("accuracy", float('nan')),
                    product_metrics.get("clip_voting", {}).get("precision", float('nan')),
                    product_metrics.get("clip_voting", {}).get("recall", float('nan')),
                    product_metrics.get("clip_voting", {}).get("f1", float('nan')),
                    product_metrics.get("clip_voting", {}).get("auc", float('nan')),
                    product_metrics.get("clip_voting", {}).get("specificity", float('nan')),
                    product_metrics.get("clip_voting", {}).get("mcc", float('nan'))
                ],
                "纯VLLM算法": [
                    product_metrics.get("vllm_only", {}).get("accuracy", float('nan')),
                    product_metrics.get("vllm_only", {}).get("precision", float('nan')),
                    product_metrics.get("vllm_only", {}).get("recall", float('nan')),
                    product_metrics.get("vllm_only", {}).get("f1", float('nan')),
                    product_metrics.get("vllm_only", {}).get("auc", float('nan')),
                    product_metrics.get("vllm_only", {}).get("specificity", float('nan')),
                    product_metrics.get("vllm_only", {}).get("mcc", float('nan'))
                ],
                "组合算法": [
                    product_metrics.get("combined", {}).get("accuracy", float('nan')),
                    product_metrics.get("combined", {}).get("precision", float('nan')),
                    product_metrics.get("combined", {}).get("recall", float('nan')),
                    product_metrics.get("combined", {}).get("f1", float('nan')),
                    product_metrics.get("combined", {}).get("auc", float('nan')),
                    product_metrics.get("combined", {}).get("specificity", float('nan')),
                    product_metrics.get("combined", {}).get("mcc", float('nan'))
                ]
            })
            
            st.dataframe(metrics_df, use_container_width=True)
            
            # 显示类别级指标
            for alg in ["clip_voting", "vllm_only", "combined"]:
                if "class_metrics" in product_metrics.get(alg, {}):
                    alg_names = {"clip_voting": "CLIP投票算法", "vllm_only": "纯VLLM算法", "combined": "组合算法"}
                    st.markdown(f"#### {alg_names[alg]}的各缺陷类型准确率")
                    
                    class_metrics = product_metrics[alg].get("class_metrics", {})
                    class_data = []
                    
                    for class_name, metrics in class_metrics.items():
                        class_data.append({
                            "缺陷类型": class_name,
                            "准确率": metrics.get("accuracy", float('nan')),
                            "正确样本数": metrics.get("correct", 0),
                            "总样本数": metrics.get("total", 0)
                        })
                    
                    class_df = pd.DataFrame(class_data)
                    st.dataframe(class_df, use_container_width=True)
        
        # 显示算法比较报告
        report_path = os.path.join(result_dir, "algorithm_comparison_report.md")
        if os.path.exists(report_path):
            with st.expander("查看算法比较报告", expanded=False):
                with open(report_path, 'r', encoding='utf-8') as f:
                    report_content = f.read()
                st.markdown(report_content)
                
                # 提供下载报告选项
                st.download_button(
                    label="下载算法比较报告 (Markdown)",
                    data=report_content,
                    file_name="algorithm_comparison_report.md",
                    mime="text/markdown"
                )
    
    # 结果可视化页面
    with tab3:
        st.header("算法比较可视化")
        
        # 检查结果目录
        if not os.path.exists(result_dir):
            st.warning("未找到评估结果目录")
            return
        
        # 检查是否存在图表
        charts_dir = os.path.join(result_dir, "charts")
        if not os.path.exists(charts_dir):
            st.warning("未找到可视化图表")
            return
        
        # 显示算法整体对比图表
        overall_chart_path = os.path.join(charts_dir, "algorithm_comparison_metrics.png")
        if os.path.exists(overall_chart_path):
            st.subheader("算法性能指标对比")
            st.image(overall_chart_path)
        
        # 显示各指标的产品级别对比
        metrics_to_show = ["accuracy", "f1", "recall", "precision"]
        metric_names = {"accuracy": "准确率", "f1": "F1分数", "recall": "召回率", "precision": "精确率"}
        
        for metric in metrics_to_show:
            product_chart_path = os.path.join(charts_dir, f"product_comparison_{metric}.png")
            if os.path.exists(product_chart_path):
                st.subheader(f"各产品的{metric_names[metric]}对比")
                st.image(product_chart_path)
        
        # 交互式图表
        st.subheader("交互式算法对比图表")
        
        # 加载结果数据
        summary_path = os.path.join(result_dir, "algorithm_comparison_summary.json")
        if os.path.exists(summary_path):
            with open(summary_path, 'r', encoding='utf-8') as f:
                all_metrics = json.load(f)
            
            # 排除平均指标
            products = [p for p in all_metrics.keys() if p != "average"]
            
            # 选择指标
            metric_to_plot = st.selectbox(
                "选择要可视化的指标",
                ["accuracy", "precision", "recall", "f1", "specificity", "mcc"],
                format_func=lambda x: metric_names.get(x, x)
            )
            
            # 准备数据
            data = []
            for product in products:
                product_metrics = all_metrics.get(product, {})
                for alg in ["clip_voting", "vllm_only", "combined"]:
                    alg_metrics = product_metrics.get(alg, {})
                    value = alg_metrics.get(metric_to_plot, float('nan'))
                    if not np.isnan(value):
                        data.append({
                            "产品": product,
                            "算法": {"clip_voting": "CLIP投票算法", "vllm_only": "纯VLLM算法", "combined": "组合算法"}[alg],
                            "指标值": value
                        })
            
            if data:
                df = pd.DataFrame(data)
                
                # 创建交互式图表
                fig, ax = plt.subplots(figsize=(12, 8))
                
                # 绘制分组柱状图
                sns.barplot(x="产品", y="指标值", hue="算法", data=df, ax=ax)
                
                ax.set_title(f"各算法在不同产品上的{metric_names[metric_to_plot]}对比")
                ax.set_ylabel(metric_names[metric_to_plot])
                ax.set_xlabel("产品")
                ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha="right")
                plt.tight_layout()
                
                st.pyplot(fig)
                
                # 提供下载选项
                with st.expander("查看数据表格"):
                    st.dataframe(df)
                    
                    # 将数据转换为CSV格式
                    csv = df.to_csv(index=False)
                    st.download_button(
                        label="下载数据 (CSV)",
                        data=csv,
                        file_name=f"algorithm_comparison_{metric_to_plot}.csv",
                        mime="text/csv"
                    ) 